<template>
    <div class="demo1">
        <div class="demo1-header">
            <span class="header-info">一、input元素实现单文件上传</span>
        </div>
        <div class="demo1-content">
            <div class="content-core">
                <!-- 注:input标签中添加上 'multiple' 属性可以选择多个文件 -->
                <input type="file" multiple @change="fileSelectChange">
            </div>
            <div class="content-info">
                <el-button type="success" @click="fileUploadByBlob">发送请求:处理成formData</el-button>
                <el-button type="info" @click="fileUploadByBase64">发送请求:处理成Base64编码</el-button>
            </div>
        </div>
    </div>
</template>
  
<script>
import { reqFileUploadByBlob, reqFileUploadByBase64 } from "@/api/fileUpload.js";
export default{
    name:"demo1",
    data:()=>{
        return {
            count:0,
            fileDataByFormData:null,  //构建的formData对象
            fileDataByFileBase64:null,  //文件base64编码方式
            fileName:""  //文件名
        }
    },
    methods:{
        /**
         * 前端给后端发送文件两张传输方式:二进制blob传输、base64传输
         * 
         */
        //文件选择事件
        fileSelectChange(event){
            const _this = this;
            /*
                event.target.files可以获取到选择的文件类数组对象
                event.target.files.length获取到文件选择的数量
                const selectedFile = event.target.files[0];
                selectedFile.name文件名称
                selectedFile.size文件大小
                selectedFile.type文件类型
                注：目前selectedFile是File对象的一个实例，相当于 new File(['abcd'],'文件名');
                注：File对象是Blob对象的一个子类，可以将File对象转为Blob对象，同时，它们也可以互转 new Blob([selectedFile]);
                注：Blob实例二进制数据，可以对其进行类似字符串的切割操作，这也是大文件分割成小文件上传的原理
                注：FileReader对象是我们文件读取对象，它可以将File或Blob对象转为 formData对象或者base64格式
                注：formData对象是我们传输二进制blob的载体，向后端接口传输数据.(form表单提交的数据也是这样)
            */
            let selectedFile = event.target.files[0];  //获取到选择的一个文件
            this.fileName = selectedFile.name;
            let sliceBlob = new Blob([selectedFile]).slice(0,5000);  //将文件转为blob二进制并进行了切割
            //let sliceFile = new File([sliceBlob],selectedFile.name);  //切割后的二进制数据重新转为了文件对象
            const fr = new FileReader();  //new FlieReader的一个实例
            fr.readAsDataURL(selectedFile);  //将File或Blob 进行读取 并转为base64格式 (base64可以给image标签赋值给src直接显示图片)
            //fr.readAsText(sliceFile);  //将File或Blob 进行读取 并转为text格式
            //fr.readAsArrayBuffer(selectedFile);  //将File或Blob 进行读取 并转为base64格式
            //读取并转化完毕:异步执行
            fr.onload = () => {
                //在fr.onload中获取结果
                // console.log(fr.result);
                _this.fileDataByFileBase64 = fr.result;
            }

            //准备formData对象，用于向后端传输 multipartFile
            const formData = new FormData();
            formData.append("multipartFile",selectedFile);  //将选择的文件对象添加进去 append("文件名",文件对象实例)
            //formData.append("username","张三");  //同时也可以搭载别的信息
            _this.fileDataByFormData = formData;
            //两种方式向后端发请求
        },
        //发送请求1
        async fileUploadByBlob(){
            let res = await reqFileUploadByBlob(this.fileDataByFormData);
            //弹出结果
            alert(JSON.stringify(res));
            console.log("文件上传api-blob二进制",res);
        },
        //发送请求2
        async fileUploadByBase64 () {
            //处理成安全Base64编码
            let dealStr = "";  //处理后的base64编码
            try {
                let findIndex = this.fileDataByFileBase64.indexOf(",") + 1;
                dealStr = this.fileDataByFileBase64.slice(findIndex);
            } catch (error) {
                console.log(error);
            }
            let res = await reqFileUploadByBase64([{fileName:this.fileName,fileBase64:dealStr}]);
            //弹出结果
            alert(JSON.stringify(res));
            console.log("文件上传api-Base64编码",res);
        }
    }
}
</script>

<style scoped>
.demo1{
    width: 100%;
    height: 100%;
    padding: 20px;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    align-items: center;
}
.demo1-header{
    display: flex;
    flex-direction: column;
    align-items: center;
    margin-bottom: 100px;
    color: blue;
}
.content-info{
    margin: 100px 0;
}
</style>